/**
 * #### 声明一个Curried类型，用于函数柯里化
 */
type Curried<A, R> = A extends []
  ? () => R // 如果A为空数组，则返回一个无参数的函数，返回值为R
  : A extends [infer ARG] // 如果A只有一个参数，则返回一个接受一个参数的函数，返回值为R
  ? (param: ARG) => R
  : A extends [infer ARG, ...infer REST] // 如果A有多个参数，则返回一个接受第一个参数的函数，返回值为Curried<REST, R>
  ? (param: ARG) => Curried<REST, R>
  : never; // 否则返回never

/**
 * #### 声明一个curry函数，用于将一个多参数函数转换为柯里化函数
 * @param fn 多参数函数
 */
declare function curry<A extends any[], R>(
  fn: (...args: A) => R // 接受一个多参数函数，返回值为R
): Curried<A, R>; // 返回一个柯里化函数

/**
 * #### 声明一个debounce函数，用于防抖
 * @param fn 函数
 * @param duration 持续时长 ms
 */
declare function debounce<A extends any[], R>(
  fn: (...args: A) => R, // 接受一个多参数函数，返回值为R
  duration?: number // 可选参数，表示防抖时间
): (...args: A) => void; // 返回一个接受多参数的函数，无返回值
// function sum(a: number, b: number, c: number) {
//   return a + b + c;
// }

// const curriedSum = curry(sum);

// const su = curriedSum(1)(2);
// console.log(su(4));
